﻿using Hx.ADSyncPlatform.ActiveDirectory.Attributes;
using Microsoft.AspNetCore.Http;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Hx.ADSyncPlatform.Common.ExportExcel
{
    public class ExcelHelper
    {


        /// <summary>
        /// 导出数据到excel
        /// </summary>
        /// <param name="list<person>">数据</param>
        /// <param name="adType">操作类型</param>
        /// <param name="sheetName">sheet名称</param>
        /// <returns></returns>
        public static MemoryStream ExportExcels<T>(List<T> model, string sheetName)
        {

            //创建EXCEL工作薄
            IWorkbook workBook = new XSSFWorkbook();
            //创建sheet文件表
            ISheet sheet = workBook.CreateSheet(sheetName);
            #region 创建Excel表头
            //创建表头
            IRow header = sheet.CreateRow(0);
            var property = model[0].GetType().GetProperties();
            for (int i = 0; i < property.Count(); i++)
            {
                //给表创建列单元格并填充列名称，此处只做首行列Columns创建和填充
                ICell cell = header.CreateCell(i);
                //获取中文列名
                var columnName = ((ColumnMappingAttribute)property[i].GetCustomAttributes(typeof(ColumnMappingAttribute), false)[0]).Description;
                cell.SetCellValue(columnName);
            }
            #endregion
            #region 填充Excel单元格中的数据
            //给工作薄中非表头填充数据，遍历行数据并进行创建和填充表格
            for (int i = 0; i < model.Count; i++)
            {
                IRow row = sheet.CreateRow(i + 1);//表示从整张数据表的第二行开始创建并填充数据，第一行已经创建。
                var propertyData = model[i].GetType().GetProperties();
                for (int j = 0; j < propertyData.Count(); j++)//遍历并创建每个单元格cell，将行数据填充在创建的单元格中。
                {
                    ICell cell = row.CreateCell(j);
                    cell.SetCellValue(propertyData[j].GetValue(model[i]).ToString());
                }
            }
            #endregion
            #region 工作流创建Excel文件
            //工作流写入，通过流的方式进行创建生成文件
            MemoryStream stream = new MemoryStream();
            workBook.Write(stream);
            return stream;
            #endregion

        }

        /// <summary>
        /// 导出数据到excel
        /// </summary>
        /// <param name="list<person>">数据</param>
        /// <param name="adType">操作类型</param>
        /// <param name="sheetName">sheet名称</param>
        /// <returns></returns>
        public static MemoryStream ExportExcels<T>(List<(string, List<T>)> tuples)
        {
            //创建EXCEL工作薄
            IWorkbook workBook = new XSSFWorkbook();
            tuples.ForEach(
                t =>
                {
                    string sheetName = t.Item1;
                    List<T> data = t.Item2;
                    AddExcelSheet(workBook, data, sheetName);
                });

            //工作流写入，通过流的方式进行创建生成文件
            MemoryStream stream = new MemoryStream();
            workBook.Write(stream);
            return stream;

        }


        /// <summary>
        /// 导出数据到excel
        /// </summary>
        /// <param name="list<person>">数据</param>
        /// <param name="adType">操作类型</param>
        /// <param name="sheetName">sheet名称</param>
        /// <returns></returns>
        private static void AddExcelSheet<T>(IWorkbook workBook, List<T> model, string sheetName)
        {

            //创建sheet文件表
            ISheet sheet = workBook.CreateSheet(sheetName);
            #region 创建Excel表头
            if (model.Count != 0)
            {
                //创建表头
                IRow header = sheet.CreateRow(0);
                var property = model[0].GetType().GetProperties();
                for (int i = 0; i < property.Count(); i++)
                {
                    //给表创建列单元格并填充列名称，此处只做首行列Columns创建和填充
                    ICell cell = header.CreateCell(i);
                    //获取中文列名
                    var columnName = ((ColumnMappingAttribute)property[i].GetCustomAttributes(typeof(ColumnMappingAttribute), false)[0]).Description;
                    cell.SetCellValue(columnName);
                }
                #endregion
                #region 填充Excel单元格中的数据
                //给工作薄中非表头填充数据，遍历行数据并进行创建和填充表格
                for (int i = 0; i < model.Count; i++)
                {
                    IRow row = sheet.CreateRow(i + 1);//表示从整张数据表的第二行开始创建并填充数据，第一行已经创建。
                    var propertyData = model[i].GetType().GetProperties();
                    for (int j = 0; j < propertyData.Count(); j++)//遍历并创建每个单元格cell，将行数据填充在创建的单元格中。
                    {
                        ICell cell = row.CreateCell(j);
                        if (propertyData[j].GetValue(model[i]) != null)
                        {
                            cell.SetCellValue(propertyData[j].GetValue(model[i]).ToString());
                        }
                    }
                }
            }
            #endregion


        }

        /// <summary>
        /// 1保存excel
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public static string SaveExcel(IFormFile formFile, string webRootPath)
        {

            var currentDate = DateTime.Now;
            try
            {
                var filePath = $"/UploadFile/{currentDate:yyyyMMdd}/";

                //创建每日存储文件夹
                if (!Directory.Exists(webRootPath + filePath))
                {
                    Directory.CreateDirectory(webRootPath + filePath);
                }

                if (formFile != null)
                {
                    //文件后缀
                    var fileExtension = Path.GetExtension(formFile.FileName);//获取文件格式，拓展名

                    //判断文件大小
                    var fileSize = formFile.Length;

                    if (fileSize > 1024 * 1024 * 10) //10M TODO:(1mb=1024X1024b)
                    {
                        throw new Exception("上传的文件不能大于10M");
                    }

                    //保存的文件名称(以名称和保存时间命名)
                    var saveName = formFile.FileName.Substring(0, formFile.FileName.LastIndexOf('.')) + "_" + currentDate.ToString("HHmmss") + fileExtension;
                    //完整的文件路径
                    var completeFilePath = webRootPath + filePath + saveName;
                    //文件保存
                    using (var fs = System.IO.File.Create(completeFilePath))
                    {
                        formFile.CopyTo(fs);
                        fs.Flush();
                    }



                    return completeFilePath;
                }
                else
                {
                    throw new Exception("上传失败，未检测上传的文件信息");
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}
